
"""
1,绘制一下函数的图像：

2, 创建一个DataFrame(df)，用data做数据，labels做行索引
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
    'age': [2.5, 3, 0.5, 3.6, 5, 2, 4.5, 5, 7, 3],
    'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
    'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
    labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
问题：
	(1)选择df中列标签为animal和 age的数据
	(2)选择visuts大于2的行
	(3)将f行的age改为1.5
	(4)计算visits列的数据总和

Tips：今天的作业涉及到一些函数，先在网上查一下用法，AI工作中也会涉及到这样的模式
"""
import math

from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pandas as pd
class Practice0813:

    def __init__(self  , *args):
        self.data = args[0]
        self.labels = args[1]


    def create_demo_table(self):
        data = [['tom', 20, 90],
                ['jerry', 90, 56],
                ['kette', 88, 86]]
        df =  pd.DataFrame(data, columns=['name', 'math', 'english'], index=list('ABC'))
        print(df)


    def create_demo_table_upt(self):
        df = pd.DataFrame({
            'A': [1, 2, 3],
            'B': [4, 5, 6],
            'C': [7, 8, 9]
        })
        print('原始数据：')
        print(df)
        # 使用.loc[]修改数据
        df.loc[0, 'A'] = 10  # 将第一行（索引为0）的'A'列的值修改为10

        # 使用.iloc[]修改数据
        df.iloc[1, 1] = 15  # 将第二行第二列（索引为1, 1）的值修改为15

        # 使用.at[]和.iat[]修改数据（针对单个值）
        df.at[0, 'B'] = 20  # 等同于df.loc[0, 'B'] = 20
        df.iat[2, 0] = 30  # 等同于df.iloc[2, 0] = 30
        print('修改后数据：')
        print(df)


    def crate_chat_demo(self):
        # 引入3D模块 画3D图  ？
        # 画图：x ** 2 + y **2
        # z = np.square(x) + np.square(y)
        # 构建等差数列  大小 -10 至 10 的数 100个元素
        x = np.linspace(-10, 10, 100)
        y = np.linspace(-10, 10, 100)
        # 生成网格点坐标矩阵，这步是必须的
        x, y = np.meshgrid(x, y)
        z = np.square(x) + np.square(y)
        # 生成画布
        fig = plt.figure()
        # 生成三维坐标系
        #axes = Axes3D(fig) #低版本的用法 matplotlib 3.4版本后已弃用
        axes = fig.add_subplot(111 , projection='3d')
        axes.plot_surface(x, y, z, cmap='rainbow')  # 画图三维图
        axes.view_init(10)  # 设置显示的角度
        plt.show()

    def crate_chat2_demo(self):
        #1,绘制一下函数的图像：
        x = np.linspace(-10 , 10 , 100)
        y = float(1) / (1 + np.exp(-x))
        plt.plot(x , y)
        plt.show()

    def math_fun_demo(self):
        #数学函数的计算测试 math.exp(-x)  math.e代表自然对数的底数e
        #在math.exp()函数中，底数始终是自然对数的底数e，约等于2.718281828459045。这个函数的作用是计算e的任意次幂。
        #当你调用math.exp(x)时，你实际上是在计算e^x，其中e是固定的底数，x是你提供的指数。
        # 因此，对于math.exp(-1)：
        #     底数仍然是e（约等于2.718281828459045）。
        #     指数是 - 1。
        # 所以，math.exp(-1) 计算的是e^−1，即e的 - 1次方。这个值约等于0.36787944117144233（但请注意，实际计算时你会得到更精确的结果，因为Python的math.exp()函数使用了高精度的算法）。
        # 总结来说，math.exp(-1)的底数是e，而它计算的是e的 - 1次方

        print(f'math.e={math.e}')
        print(f'math.e={math.e ** 2}')
        print(f'math.exp(0)={math.exp(0)}')
        print(f'np.exp(0)  ={np.exp(0)}')
        print('*' * 20)
        print(f'math.exp(-1)={math.exp(-1)}')
        print(f'np.exp(-1)  ={np.exp(-1)}')
        print('*' * 20)
        print(f'math.exp(-2)={math.exp(-2)}')
        print(f'np.exp(-2)  ={np.exp(-2)}')
        print('*' * 20)
        print(f'math.exp(1)={math.exp(1)}')
        print(f'np.exp(1)  ={np.exp(1)}')
        print('*' * 20)
        print(f'math.exp(2)={math.exp(2)}')
        print(f'np.exp(2)  ={np.exp(2)}')
        print('*' * 20)
        print(f'math.exp(3)={math.exp(3)}')
        print(f'np.exp(3)  ={np.exp(3)}')

    def crate_chat(self):
        # 绘制图像
        # 画图：这张图片展示了一个数学表达式。表达式是：y = 1 / (1 + e^(-x))。这个表达式是一个指数函数，其中e是自然对数的底数
        #在Python中计算e^(-x)时，应使用math.exp(-x)，因为Python没有直接的^运算符来表示指数运算（它用于按位异或操作），并且math.e代表自然对数的底数e
        # 定义x的范围 np.linspace函数生成了一个从-10到10的线性空间向量，这个向量有400个点，这样可以保证图像比较平滑。
        x = np.linspace(-10, 10, 400)  # 从-10到10，共400个点
        y = 1 / (1 + np.exp(-x)) # 计算y的值
        # 绘制图像
        plt.plot(x, y)
        plt.title('Plot of y = 1 / (1 + e^(-x))')
        plt.xlabel('x')
        plt.ylabel('y')
        plt.grid(True)  # 显示网格
        plt.show()

    def create_table(self):

        # 生成表格 , 'visits' , 'priority'
        df_table = pd.DataFrame(data, columns=['animal','visits' , 'priority', 'age'], index=list(labels))
        print(df_table)
        #(1)选择df中列标签为animal和 age的数据
        #第一种方法  根据列名选择
        #select_data = df_table[['animal','age']]
        # 第二种方法： 根据列名选择 使用.loc[]选择列（不推荐仅用于列选择）
        #select_data = df_table.loc[:,['animal', 'age']]
        #第三种方法  df_table.iloc 根据列所有选择
        select_data = df_table.iloc[:, [0, 3]]
        print(f'择df中列标签为animal和 age的数据：{select_data}')
        print('*' * 50)
        #(2)选择visuts大于2的行 # 过滤数据 满足条件展示 ， 里面是条件
        # df_table_filter = df_table[df_table['visits'] > 2]
        # print(df_table_filter)
        #(3)将f行的age改为1.5
        df_table.loc['f', 'age'] = 2.5  # 将第6行（索引为f）的'age'列的值修改为2.5
        #(4)计算visits列的数据总和
        print(f'计算visits列的数据总和：{df_table["visits"].sum()}')
        # visits列和age的数据相加
        column_add = df_table.apply(lambda x: x['visits'] + x['age'], axis=1)
        print('visits列和age的数据相加：')
        print(column_add)
        df_table['sum'] = df_table.apply(lambda x: x['visits'] + x['age'], axis=1)  #

        print(df_table)


#初始化数据
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
                'age': [2.5, 3, 0.5, 3.6, 5, 2, 4.5, 5, 7, 3],
                'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
                'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

obj = Practice0813(data , labels)
# obj.create_demo_table()
#obj.create_demo_table_upt()
# obj.create_table()
# obj.crate_chat_demo()
# obj.crate_chat2_demo()
obj.crate_chat()
# obj.math_fun_demo()